﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;

namespace XUJson2CS
{
    namespace Editor
    {
        internal class XUJsonConverter
        {
            [MenuItem("Assets/XUJson2CS/Convert", false, 2)]
            public static void Convert()
            {
                XUJsonConverterSetting setting = XUJsonConverterSetting.LoadOrCreate();
                if (string.IsNullOrEmpty(setting.jsonFolder) || !Directory.Exists(setting.jsonFolder))
                {
                    EditorUtility.DisplayDialog("错误", "json 路径错误", "确定");
                }
                else if (string.IsNullOrEmpty(setting.csFolder) || !Directory.Exists(setting.csFolder))
                {
                    EditorUtility.DisplayDialog("错误", "cs 路径错误", "确定");
                }
                else
                {
                    Generate(setting.jsonFolder, setting.csFolder + "/Config.cs");
                    AssetDatabase.Refresh();
                }
            }

            static public void Generate(string jsonDir, string saveFilePath)
            {
                try
                {
                    if (string.IsNullOrEmpty(saveFilePath))
                    {
                        throw new Exception("savePath不能为空");
                    }

                    if (Directory.Exists(jsonDir))
                    {
                        List<string> jsonFiles = new List<string>(Directory.GetFiles(jsonDir, "*.json", SearchOption.AllDirectories));
                        if (jsonFiles.Count > 0)
                        {
                            OpenSaveFile(saveFilePath);

                            jsonFiles.Sort();
                            foreach (string jsonFile in jsonFiles)
                            {
                                ParseJson(saveFilePath, jsonFile);
                            }

                            CloseSaveFile(saveFilePath);
                        }
                        else
                        {
                            throw new Exception("找不到json文件：" + jsonDir);
                        }
                    }
                    else
                    {
                        throw new Exception("找不到目录：" + jsonDir);
                    }
                }
                catch (Exception ex)
                {
                    File.AppendAllText(saveFilePath, ex.ToString(), Encoding.UTF8);
                }
            }

            static private void OpenSaveFile(string savePath)
            {
                List<string> head = new List<string>();
                head.Add("/** 所有json配置对应生成的class，自动生成，请不要修改 */");
                head.Add("");
                head.Add("using System;");
                head.Add("using System.Collections;");
                head.Add("using System.Collections.Generic;");
                head.Add("using XUJson2CS;");
                head.Add("");
                head.Add("namespace config");
                head.Add("{");
                File.WriteAllLines(savePath, head.ToArray(), Encoding.UTF8);
            }

            static private void ParseJson(string savePath, string jsonFile)
            {
                string jsonStr = File.ReadAllText(jsonFile);
                if (string.IsNullOrEmpty(jsonStr))
                {
                    throw new Exception("错误的json文件：" + jsonFile);
                }

                Dictionary<string, object> jsonDic = MiniJSON.Json.Deserialize(jsonStr) as Dictionary<string, object>;
                if (jsonDic == null || jsonDic.Count == 0)
                {
                    throw new Exception("错误的json文件：" + jsonFile);
                }

                foreach (var field in jsonDic)
                {
                    int id = 0;
                    bool result = int.TryParse(field.Key, out id);
                    if (result)
                    {
                        if (id > 0)
                        {
                            ParseJsonClass(savePath, jsonFile, jsonDic, id);
                        }
                        else
                        {
                            throw new Exception("id必须大于0，检查配置：" + jsonFile);
                        }
                    }
                    else
                    {
                        ParseJsonClass(savePath, jsonFile, jsonDic, -1);
                    }
                    break;
                }
            }

            static private void ParseJsonClass(string savePath, string jsonFile, Dictionary<string, object> jsonDic, int id)
            {
                string className = Path.GetFileNameWithoutExtension(jsonFile);

                if (id > 0)
                {
                    Dictionary<string, object> fieldValueDic = new Dictionary<string, object>();
                    foreach (var field in jsonDic)
                    {
                        if (field.Value is IDictionary)
                        {
                            Dictionary<string, object> elements = field.Value as Dictionary<string, object>;

                            //这种配置格式类型是不固定的
                            if (elements.Count == 2 && elements.ContainsKey("type") && elements.ContainsKey("value"))
                            {
                                if (!fieldValueDic.ContainsKey("type"))
                                {
                                    fieldValueDic.Add("type", elements["type"]);
                                }
                                if (!fieldValueDic.ContainsKey("value"))
                                {
                                    fieldValueDic.Add("value", new CSObject());
                                }
                                continue;
                            }

                            foreach (var element in elements)
                            {
                                if (element.Value is IList)
                                {
                                    if ((element.Value as IList).Count > 0)
                                    {
                                        if (!fieldValueDic.ContainsKey(element.Key))
                                        {
                                            fieldValueDic.Add(element.Key, element.Value);
                                        }
                                    }
                                }
                                else if (element.Value is IDictionary)
                                {
                                    if ((element.Value as IDictionary).Count > 0)
                                    {
                                        if (!fieldValueDic.ContainsKey(element.Key))
                                        {
                                            fieldValueDic.Add(element.Key, element.Value);
                                        }
                                        else
                                        {
                                            foreach (var item in (element.Value as Dictionary<string, object>))
                                            {
                                                if ((fieldValueDic[element.Key] as Dictionary<string, object>).ContainsKey(item.Key) == false)
                                                {
                                                    (fieldValueDic[element.Key] as Dictionary<string, object>).Add(item.Key, item.Value);
                                                }
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    if (!fieldValueDic.ContainsKey(element.Key))
                                    {
                                        fieldValueDic.Add(element.Key, element.Value);
                                    }
                                }
                            }
                        }
                        else if (field.Value is IList)
                        {
                            if (fieldValueDic.Count == 0)
                            {
                                fieldValueDic.Add("values", new List<object>() { new Dictionary<string, object>() });
                            }
                            Dictionary<string, object> tempDic = (fieldValueDic["values"] as List<object>)[0] as Dictionary<string, object>;
                            List<object> valueList = field.Value as List<object>;
                            foreach (var value in valueList)
                            {
                                Dictionary<string, object> elements = value as Dictionary<string, object>;
                                foreach (var element in elements)
                                {
                                    if (element.Value is IList)
                                    {
                                        if ((element.Value as IList).Count > 0)
                                        {
                                            if (!tempDic.ContainsKey(element.Key))
                                            {
                                                tempDic.Add(element.Key, element.Value);
                                            }
                                        }
                                    }
                                    else if (element.Value is IDictionary)
                                    {
                                        if ((element.Value as IDictionary).Count > 0)
                                        {
                                            if (!tempDic.ContainsKey(element.Key))
                                            {
                                                tempDic.Add(element.Key, element.Value);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (!tempDic.ContainsKey(element.Key))
                                        {
                                            tempDic.Add(element.Key, element.Value);
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            throw new Exception(jsonFile + "错误的id-dictionary结构：" + field.Key);
                        }
                    }
                    if (!fieldValueDic.ContainsKey("id"))
                    {
                        fieldValueDic.Add("id", 0L);
                    }
                    ParseJsonClassGen(savePath, className, "", true, fieldValueDic);
                }
                else
                {
                    ParseJsonClassGen(savePath, className, "", false, jsonDic);
                }

                File.AppendAllText(savePath, "\n", Encoding.UTF8);
            }

            static private string ParseJsonClassGen(string savePath, string parentName, string fieldName, bool isIDValueStruct, Dictionary<string, object> fieldValue)
            {
                //获取类名
                string className = string.IsNullOrEmpty(fieldName) ? parentName : parentName + "_" + fieldName;

                List<string> classContent = new List<string>();

                //设置类名
                Push(classContent, "/**" + className + "*/", 1);
                if (string.IsNullOrEmpty(fieldName))
                {
                    Push(classContent, "public class " + className + " : XUConfig<" + className + "> {", 1);
                }
                else
                {
                    Push(classContent, "public class " + className + " {", 1);
                }

                Dictionary<string, string> classNameSubDic = new Dictionary<string, string>();
                Dictionary<string, string> classNameSubDic1 = new Dictionary<string, string>();

                Dictionary<string, KeyValuePair<string, int>> fieldTypeMap = new Dictionary<string, KeyValuePair<string, int>>();

                //声明字段
                foreach (var field in fieldValue)
                {
                    //获取字段名
                    string fieldNameSub = field.Key;

                    //获取字段类型
                    if (IsNumber(field.Value.GetType()))
                    {
                        fieldTypeMap.Add(fieldNameSub, new KeyValuePair<string, int>("float", 2));
                    }
                    else if (field.Value is string)
                    {
                        fieldTypeMap.Add(fieldNameSub, new KeyValuePair<string, int>("string", 2));
                    }
                    else if (field.Value is bool)
                    {
                        fieldTypeMap.Add(fieldNameSub, new KeyValuePair<string, int>("bool", 2));
                    }
                    else if (field.Value is IList)
                    {
                        List<object> valueList = (List<object>)field.Value;
                        if (valueList.Count > 0)
                        {
                            var firstElement = valueList[0];
                            if (IsNumber(firstElement.GetType()))
                            {
                                fieldTypeMap.Add(fieldNameSub, new KeyValuePair<string, int>("XUSafeArray<float>", 2));
                            }
                            else if (firstElement is string)
                            {
                                fieldTypeMap.Add(fieldNameSub, new KeyValuePair<string, int>("XUSafeArray<string>", 2));
                            }
                            else if (firstElement is bool)
                            {
                                fieldTypeMap.Add(fieldNameSub, new KeyValuePair<string, int>("XUSafeArray<bool>", 2));
                            }
                            else if (firstElement is IList)
                            {
                                List<object> firstList = (List<object>)firstElement;

                                int index = 1;
                                while (firstList.Count == 0)
                                {
                                    if (index < valueList.Count)
                                    {
                                        firstList = (List<object>)valueList[index++];
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }

                                if (firstList.Count > 0)
                                {
                                    var secondElement = firstList[0];
                                    if (IsNumber(secondElement.GetType()))
                                    {
                                        fieldTypeMap.Add(fieldNameSub, new KeyValuePair<string, int>("XUSafeArray<XUSafeArray<float>>", 2));
                                    }
                                    else if (secondElement is string)
                                    {
                                        fieldTypeMap.Add(fieldNameSub, new KeyValuePair<string, int>("XUSafeArray<XUSafeArray<string>>", 2));
                                    }
                                    else if (secondElement is bool)
                                    {
                                        fieldTypeMap.Add(fieldNameSub, new KeyValuePair<string, int>("XUSafeArray<XUSafeArray<bool>>", 2));
                                    }
                                    else if (secondElement is IList)
                                    {
                                        List<object> secondList = (List<object>)secondElement;
                                        if (secondList.Count > 0)
                                        {
                                            var thirdElement = secondList[0];
                                            if (IsNumber(thirdElement.GetType()))
                                            {
                                                fieldTypeMap.Add(fieldNameSub, new KeyValuePair<string, int>("XUSafeArray<XUSafeArray<XUSafeArray<float>>>", 2));
                                            }
                                            else if (thirdElement is string)
                                            {
                                                fieldTypeMap.Add(fieldNameSub, new KeyValuePair<string, int>("XUSafeArray<XUSafeArray<XUSafeArray<string>>>", 2));
                                            }
                                            else if (thirdElement is bool)
                                            {
                                                fieldTypeMap.Add(fieldNameSub, new KeyValuePair<string, int>("XUSafeArray<XUSafeArray<XUSafeArray<bool>>>", 2));
                                            }
                                            else if (thirdElement is IList)
                                            {
                                                throw new Exception(className + "不支持超过3维数组：" + fieldNameSub + " = " + thirdElement.GetType());
                                            }
                                            else if (thirdElement is IDictionary)
                                            {
                                                throw new Exception(className + "不支持在3维及以上数组实现key-value类型：" + fieldNameSub + " = " + thirdElement.GetType());
                                            }
                                            else
                                            {
                                                throw new Exception(className + "无法识别的字段类型：" + fieldNameSub + " = " + thirdElement.GetType());
                                            }
                                        }
                                        else
                                        {
                                            fieldTypeMap.Add(fieldNameSub, new KeyValuePair<string, int>("XUSafeArray<XUSafeArray<XUSafeArray<object>>>", 2));
                                        }
                                    }
                                    else if (secondElement is IDictionary)
                                    {
                                        throw new Exception(className + "不支持在2维及以上数组实现key-value类型：" + fieldNameSub + " = " + secondElement.GetType());
                                    }
                                    else
                                    {
                                        throw new Exception(className + "无法识别的字段类型：" + fieldNameSub + " = " + secondElement.GetType());
                                    }
                                }
                                else
                                {
                                    fieldTypeMap.Add(fieldNameSub, new KeyValuePair<string, int>("XUSafeArray<XUSafeArray<object>>", 2));
                                }
                            }
                            else if (firstElement is IDictionary)
                            {
                                string classNameSub = ParseJsonClassGen(savePath, className, fieldNameSub, isIDValueStruct, firstElement as Dictionary<string, object>);
                                classNameSubDic1.Add(fieldNameSub, classNameSub);
                                fieldTypeMap.Add(fieldNameSub, new KeyValuePair<string, int>("XUSafeArray<" + classNameSub + ">", 2));
                            }
                            else
                            {
                                throw new Exception(className + "无法识别的字段类型：" + fieldNameSub + " = " + firstElement.GetType());
                            }
                        }
                        else
                        {
                            fieldTypeMap.Add(fieldNameSub, new KeyValuePair<string, int>("XUSafeArray<object>", 2));
                        }
                    }
                    else if (field.Value is IDictionary)
                    {
                        string classNameSub = ParseJsonClassGen(savePath, className, fieldNameSub, isIDValueStruct, field.Value as Dictionary<string, object>);
                        classNameSubDic.Add(fieldNameSub, classNameSub);
                        fieldTypeMap.Add(fieldNameSub, new KeyValuePair<string, int>(classNameSub, 2));
                    }
                    else if (field.Value is CSObject)
                    {
                        fieldTypeMap.Add(fieldNameSub, new KeyValuePair<string, int>("object", 2));
                    }
                    else
                    {
                        throw new Exception(className + "无法识别的字段类型：" + fieldNameSub + " = " + field.Value.GetType());
                    }

                    Push(classContent, string.Format("public {0} {1} {{ get; private set; }}", fieldTypeMap[fieldNameSub].Key, fieldNameSub), fieldTypeMap[fieldNameSub].Value);
                }

                //声明Parse函数
                if (string.IsNullOrEmpty(fieldName))
                {
                    Push(classContent, "public override void Parse(Dictionary<string, object> json) {", 2);
                }
                else
                {
                    Push(classContent, "public void Parse(Dictionary<string, object> json) {", 2);
                }
                Push(classContent, "if(json == null) return ;", 3);
                foreach (var field in fieldValue)
                {
                    //获取字段名
                    string fieldNameSub = field.Key;

                    Push(classContent, "/**this." + fieldNameSub + " */", 3);

                    //获取字段类型
                    if (IsNumber(field.Value.GetType()))
                    {
                        Push(classContent, string.Format("this.{0} = json.ContainsKey(\"{1}\") ? Convert.ToSingle(json[\"{2}\"]) : default;", fieldNameSub, fieldNameSub, fieldNameSub), 3);
                    }
                    else if (field.Value is string)
                    {
                        Push(classContent, string.Format("this.{0} = json.ContainsKey(\"{1}\") ? Convert.ToString(json[\"{2}\"]) : string.Empty;", fieldNameSub, fieldNameSub, fieldNameSub), 3);
                    }
                    else if (field.Value is bool)
                    {
                        Push(classContent, string.Format("this.{0} = json.ContainsKey(\"{1}\") ? Convert.ToBoolean(json[\"{2}\"]) : false;", fieldNameSub, fieldNameSub, fieldNameSub), 3);
                    }
                    else if (field.Value is IList)
                    {
                        List<object> valueList = (List<object>)field.Value;
                        if (valueList.Count > 0)
                        {
                            var firstElement = valueList[0];
                            if (IsNumber(firstElement.GetType()))
                            {
                                Push(classContent, string.Format("this.{0} = new XUSafeArray<float>((json[\"{1}\"] as List<object>).ConvertAll({2}));", fieldNameSub, fieldNameSub, GetConvertFunc("float")), 3);
                            }
                            else if (firstElement is string)
                            {
                                Push(classContent, string.Format("this.{0} = new XUSafeArray<string>((json[\"{1}\"] as List<object>).ConvertAll({2}));", fieldNameSub, fieldNameSub, GetConvertFunc("string")), 3);
                            }
                            else if (firstElement is bool)
                            {
                                Push(classContent, string.Format("this.{0} = new XUSafeArray<bool>((json[\"{1}\"] as List<object>).ConvertAll({2}));", fieldNameSub, fieldNameSub, GetConvertFunc("bool")), 3);
                            }
                            else if (firstElement is IList)
                            {
                                List<object> firstList = (List<object>)firstElement;

                                int index = 1;
                                while (firstList.Count == 0)
                                {
                                    if (index < valueList.Count)
                                    {
                                        firstList = (List<object>)valueList[index++];
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }

                                if (firstList.Count > 0)
                                {
                                    var secondElement = firstList[0];
                                    if (IsNumber(secondElement.GetType()))
                                    {
                                        PushXUSafeArrayByListOne(classContent, "float", fieldNameSub, 3);
                                    }
                                    else if (secondElement is string)
                                    {
                                        PushXUSafeArrayByListOne(classContent, "string", fieldNameSub, 3);
                                    }
                                    else if (secondElement is bool)
                                    {
                                        PushXUSafeArrayByListOne(classContent, "bool", fieldNameSub, 3);
                                    }
                                    else if (secondElement is IList)
                                    {
                                        List<object> secondList = (List<object>)secondElement;
                                        if (secondList.Count > 0)
                                        {
                                            var thirdElement = secondList[0];
                                            if (IsNumber(thirdElement.GetType()))
                                            {
                                                PushXUSafeArrayByListTwo(classContent, "float", fieldNameSub, 3);
                                            }
                                            else if (thirdElement is string)
                                            {
                                                PushXUSafeArrayByListTwo(classContent, "string", fieldNameSub, 3);
                                            }
                                            else if (thirdElement is bool)
                                            {
                                                PushXUSafeArrayByListTwo(classContent, "bool", fieldNameSub, 3);
                                            }
                                        }
                                        else
                                        {
                                            PushXUSafeArrayByListTwo(classContent, "object", fieldNameSub, 3);
                                        }
                                    }
                                }
                                else
                                {
                                    PushXUSafeArrayByListOne(classContent, "object", fieldNameSub, 3);
                                }
                            }
                            else if (firstElement is IDictionary)
                            {
                                PushXUSafeArrayByDicOne(classContent, classNameSubDic1[fieldNameSub], fieldNameSub, 3);
                            }
                        }
                        else
                        {
                            Push(classContent, string.Format("this.{0} = new XUSafeArray<object>(json[\"{1}\"] as List<object>);", fieldNameSub, fieldNameSub), 3);
                        }
                    }
                    else if (field.Value is IDictionary)
                    {
                        Push(classContent, string.Format("if (json.ContainsKey(\"{0}\") && ((ICollection)json[\"{1}\"]).Count > 0){{", fieldNameSub, fieldNameSub), 3);
                        Push(classContent, string.Format("this.{0} = new {1}();", fieldNameSub, classNameSubDic[fieldNameSub]), 4);
                        Push(classContent, string.Format("this.{0}.Parse((Dictionary<string, object>)json[\"{1}\"]);", fieldNameSub, fieldNameSub), 4);
                        Push(classContent, string.Format("}}"), 3);
                        Push(classContent, string.Format("else{{"), 3);
                        Push(classContent, string.Format("this.{0} = null;", fieldNameSub), 4);
                        Push(classContent, string.Format("}}"), 3);
                    }
                    else if (field.Value is CSObject)
                    {
                        Push(classContent, string.Format("this.{0} = json[\"{1}\"];", fieldNameSub, fieldNameSub), 3);
                    }
                }
                Push(classContent, "}", 2);

                //获取结构方式
                if (string.IsNullOrEmpty(fieldName))
                {
                    Push(classContent, "/**", 2);
                    Push(classContent, " * 是否ID-Value的结构", 2);
                    Push(classContent, " */", 2);
                    Push(classContent, "public static bool IsIDValueStruct() {", 2);
                    Push(classContent, "return " + isIDValueStruct.ToString().ToLower() + ";", 3);
                    Push(classContent, "}", 2);
                }

                //声明GetOne函数
                if (string.IsNullOrEmpty(fieldName))
                {
                    if (isIDValueStruct)
                    {
                        Push(classContent, "/**", 2);
                        Push(classContent, " * 获取单个配置项", 2);
                        Push(classContent, " */", 2);
                        Push(classContent, "public static " + className + " GetOne(int id) {", 2);
                        Push(classContent, className + "[] array = GetAll();", 3);
                        Push(classContent, "foreach (var item in array){", 3);
                        Push(classContent, "if (item.id == id)", 4);
                        Push(classContent, "return item;", 5);
                        Push(classContent, "}", 3);
                        Push(classContent, "return null;", 3);
                        Push(classContent, "}", 2);
                    }
                    else
                    {
                        Push(classContent, "/**", 2);
                        Push(classContent, " * 获取单个配置项", 2);
                        Push(classContent, " */", 2);
                        Push(classContent, "public static " + className + " GetOne() {", 2);
                        Push(classContent, className + "[] array = GetAll();", 3);
                        Push(classContent, "if (array.Length > 0)", 3);
                        Push(classContent, "return array[0];", 4);
                        Push(classContent, "else", 3);
                        Push(classContent, "return null;", 4);
                        Push(classContent, "}", 2);
                    }
                }

                //结尾
                Push(classContent, "}", 1);

                //保存
                File.AppendAllLines(savePath, classContent.ToArray(), Encoding.UTF8);

                return className;
            }

            static private void CloseSaveFile(string savePath)
            {
                File.AppendAllText(savePath, "}", Encoding.UTF8);
            }

            /*********************************************************/

            private static void Push(List<string> list, string content, int indentCount = 1)
            {
                string indentStr = "";
                if (indentCount > 0)
                {
                    for (int i = 0; i < indentCount; i++)
                    {
                        indentStr += "\t";
                    }
                }
                content = indentStr + content;
                list.Add(content);
            }

            private static void PushXUSafeArrayByListOne(List<string> list, string type, string fieldName, int indentCount = 1)
            {
                Push(list, "List<XUSafeArray<" + type + ">> array_" + fieldName + " = new List<XUSafeArray<" + type + ">>();", indentCount);
                Push(list, "List<object> temp_" + fieldName + " = json[\"" + fieldName + "\"] as List<object>;", indentCount);
                Push(list, "for (int index = 0; index < temp_" + fieldName + ".Count; index++) {", indentCount);
                Push(list, "List<object> temp1_" + fieldName + " = temp_" + fieldName + "[index] as List<object>;", indentCount + 1);
                Push(list, "array_" + fieldName + ".Add(new XUSafeArray<" + type + ">(temp1_" + fieldName + ".ConvertAll(" + GetConvertFunc(type) + ")));", indentCount + 1);
                Push(list, "}", indentCount);
                Push(list, "this." + fieldName + " = new XUSafeArray<XUSafeArray<" + type + ">>(array_" + fieldName + ");", indentCount);
            }

            private static void PushXUSafeArrayByListTwo(List<string> list, string type, string fieldName, int indentCount = 1)
            {
                Push(list, "List<XUSafeArray<XUSafeArray<" + type + ">>> array1_" + fieldName + " = new List<XUSafeArray<XUSafeArray<" + type + ">>>();", indentCount);
                Push(list, "List<object> temp1_" + fieldName + " = json[\"" + fieldName + "\"] as List<object>;", indentCount);
                Push(list, "for (int index = 0; index < temp1_" + fieldName + ".Count; index++) {", indentCount);
                Push(list, "List<XUSafeArray<" + type + ">> array2_" + fieldName + " = new List<XUSafeArray<" + type + ">>();", indentCount + 1);
                Push(list, "List<object> temp2_" + fieldName + " = temp1_" + fieldName + "[index] as List<object>;", indentCount + 1);
                Push(list, "for (int index1 = 0; index1 < temp2_" + fieldName + ".Count; index1++) {", indentCount + 1);
                Push(list, "List<object> temp3_" + fieldName + " = temp2_" + fieldName + "[index] as List<object>;", indentCount + 2);
                Push(list, "array2_" + fieldName + ".Add(new XUSafeArray<" + type + ">(temp3_" + fieldName + ".ConvertAll(" + GetConvertFunc(type) + ")));", indentCount + 2);
                Push(list, "}", indentCount + 1);
                Push(list, "array1_" + fieldName + ".Add(new XUSafeArray<XUSafeArray<" + type + ">>(array2_" + fieldName + "));", indentCount + 1);
                Push(list, "}", indentCount);
                Push(list, "this." + fieldName + " = new XUSafeArray<XUSafeArray<XUSafeArray<" + type + ">>>(array1_" + fieldName + ");", indentCount);
            }

            private static void PushXUSafeArrayByDicOne(List<string> list, string type, string fieldName, int indentCount = 1)
            {
                Push(list, "List<" + type + "> array_" + fieldName + " = new List<" + type + ">();", indentCount);
                Push(list, "List<object> temp_" + fieldName + " = json[\"" + fieldName + "\"] as List<object>;", indentCount);
                Push(list, "for (int index = 0; index < temp_" + fieldName + ".Count; index++) {", indentCount);
                Push(list, type + " item_" + fieldName + " = new " + type + "();", indentCount + 1);
                Push(list, "item_" + fieldName + ".Parse((Dictionary<string, object>)temp_" + fieldName + "[index]);", indentCount + 1);
                Push(list, "array_" + fieldName + ".Add(item_" + fieldName + ");", indentCount + 1);
                Push(list, "}", indentCount);
                Push(list, "this." + fieldName + " = new XUSafeArray<" + type + ">(array_" + fieldName + ");", indentCount);
            }

            //=======================================================================================================================

            /// <summary>
            /// 判断字符串是否是数字
            /// </summary>
            public static bool IsNumber(Type type)
            {
                return type == typeof(int) || type == typeof(long) || type == typeof(float) || type == typeof(double);
            }

            public static bool IsLong(Type type)
            {
                return type == typeof(long);
            }

            public static bool IsDouble(Type type)
            {
                return type == typeof(double);
            }

            public static string GetConvertFunc(string type)
            {
                string convert;
                if (type == "float")
                {
                    convert = "x => Convert.ToSingle(x)";
                }
                else if (type == "string")
                {
                    convert = "x => Convert.ToString(x)";
                }
                else if (type == "bool")
                {
                    convert = "x => Convert.ToBoolean(x)";
                }
                else
                {
                    convert = "x => (" + type + ")(x)";
                }
                return convert;
            }

            //=======================================================================================================================

            public class CSObject
            {
            }
        }
    }
}
